import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 写一个专门用于下载的工具类，让下载结果（成功与失败）交给调用方显示，实现自己调用自己写的方法（方法回调）。
 * 要点：
 * （1）写一个接口 ResultCallback，定义分别表示成功的方法success()和 表示失败的方法 failure(Exception e)
 * （2）下载类 Download包含接口ResultCallback类型的字段callback
 *     定义用于实例化类成员对象callback的构造方法 Download(ResultCallback callback)
 *     在类的下载（业务）方法 executeDownload()里，使用接口方法
 * （3）在使用类 Download的测试类里，创建接口的实例（写实现），使用业务方法实现回调效果。
 *
 * 通过接口实现回调，实际上是使用了Java的多态性，即父类引用指向子类的地址，从而实现通过接口调用其实现类的方法。
 * 通过回调类的对象，执行方法 executeDownload(url)，调用接口的匿名实现类的方法
 */

interface Callback {   //回调接口
    void success();  //成功
    void failure(Exception e);  //失败
}

class Download{   //下载类作为被调方【回调类】
    private Callback callback;    //类Download关联接口Callback

    public Download(Callback callback) {   //构造方法
        this.callback = callback;
    }

    public void download(String url){   //下载方法
        try {
            HttpURLConnection conn=(HttpURLConnection) new URL(url).openConnection();
            conn.setConnectTimeout(5*1000);
            conn.setRequestMethod("GET");
            //do download things here...
            callback.success();
        } catch (Exception e) {
            //e.printStackTrace();
            callback.failure(e);
        }
    }
}

public class InterfaceCallbackDemo {   //测试类作为调用方
    public static void main(String[] args) {
        //创建类Download的实例并使用其实例方法，回调接口参数的实现方法
        new Download(new Callback() {  //构造参数为接口类型
            @Override
            public void success() {
                System.out.println("下载完成");  //实现接口（方法）
            }

            @Override
            public void failure(Exception e) {
                System.out.println("下载失败");   //实现接口（方法）
            }
        }).download("Your URL");   //下载失败（因为不是合法的网址）
        //}).executeDownload("http://www.wustwzx.com");  //下载成功（因为是合法的网址）
    }
}
